
package DB;

import Data.*;

import java.sql.PreparedStatement;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Vector;

/**
 * Mapper Klasse, die FlightRealization Objekte auf eine relationale DB abbildet.
 * Eine Flight Realization ist eine Ausführung des Fluges, der aus einem vordefinierten FLight die Attribute übernimmt und diesem ein konkretes Datum zuweist.
 * Diese Klasse erlaubt zahlreiche Operationen, um ein flightRealization zu verwalten, z.B. eine LöschOperation oder eine EinfügeOperation
 * @author Stefan Fellner
 */
public class FlightRealizationMapper {

    /*
     * Um sicher zu stellen, dass nur eine Instanz von der Klasse erzeugt wird, wird die Singleton Pattern angewendet.
     * Durch das Schlüsselwort static wird dies erreicht.
     * Quelle: http://www.theserverside.de/singleton-pattern-in-java/
     */
    private static FlightRealizationMapper flightRealizationMapper = null;

    private ConnectionManager manager;

    //mittels protected wird sichergestellt, dass mit new keine neuen Instanzen erstellt werden können. Sobals ein Mapper Objekt erstellt wird, wird eine connection aufgebaut
    protected FlightRealizationMapper(){
        manager = ConnectionManager.getInstance();

    }

    /* Eine Instanz dieser Klasse sollte immer mittels der folgenden Methode erstellt werden.
     * Dadurch wird sicher gestellt, dass nur eine Instanz von dieser Klasse vorhanden ist.
     * @return DAS <code>FlightRealizationMapper</code> Objekt
     * @see flightRealizationMapper
     */
    public static FlightRealizationMapper getInstance(){

        if(flightRealizationMapper == null){
            flightRealizationMapper = new FlightRealizationMapper();
        }

        return flightRealizationMapper;

    }





//Es folgen nun alle Methoden, die die Tabelle flightRealization verändern können, bzw. deren inhalte abrufen können


    /* Eine FlightRealization in die Datenbank einfügen.
     * @param das FlightRealization Objekt welches hinzugefügt werden soll. Die IDs des dazugehörigen flight, aircrafts.
     * @return das eingefügte flightRealization Objekt.
     * Innerhalb dieser Methode wird der Primärschlüssel automatisch erzeugt. Der größte vorhandene Schlüssel wird um 1 erhöht.
     * Zudem muss das java date Objekt in einen sql timestamp vor der einfügeoperation mittel hilfsmethoden umgewandelt werden
     */
    public FlightRealization insert (FlightRealization flightR){
        //DB verbindung vom Connection Manager Objekt holen
        Connection con = this.manager.getConnection();

        try{




            // Leeres SQL-Statement (JDBC) anlegen
            Statement stmt = con.createStatement();

            /*
             * Zunächst schauen wir nach, welches der momentan größte
             * Primärschlüsselwert einer FlightRealization ist.
             */
            ResultSet maxId = stmt.executeQuery("SELECT MAX(realizationId) AS maxId " +"FROM flightRealization");

            //die ergebnis Tabelle muss eine maxId zurückgeben.
            if(maxId.next()){
                try{

            //das departure Date Objekt aus der Flightrealization in einen sql Date umwandeln
            java.sql.Date departureDate = utilDateToSqlDate(flightR.getDateOfDeparture());

            //das arrival Date Objekt aus der Flightrealization in einen sql Date umwandeln
            java.sql.Date arrivalDate = utilDateToSqlDate(flightR.getDateOfArrival());

                 //Das einzufügende Objekt flight erhält den neu errechneten Primärschlüssel
                 flightR.setRealizationId(maxId.getInt("maxId") + 1);

                    stmt = con.createStatement();

                     /**
                     * Jetzt erst erfolgt die tatsächliche Einfügeoperation.
                     * Die Attribute der flightRealization, werden aus der übergebenen flghtRealization mit den getter methoden geholt.
                     */
                    stmt.executeUpdate("INSERT INTO flightRealization (realizationId, dateOfDeparture, dateOfArrival, flightId, craftId) "+
                            "VALUES (" + "'"+
                            flightR.getRealizationId()+"'"+", "+"'"+
                            departureDate+"'"+", "+"'"+
                            arrivalDate+"'"+", "+"'"+
                            flightR.getRelatedFlightId()+"'"+", "+"'"+
                            flightR.getIdOfRelatedAircraft()+"'"+")");
                }
                catch(RemoteException ex){
                    ex.printStackTrace();
                }
            }

        }
        //falls die sql abfrage fehlschlägt...
        catch (SQLException e2) {
            e2.printStackTrace();
        }
        //dieses return ist notwendig, da sich die ID der flightRealization im Laufe der Methode verändert und deswegen das ganze Objekt wieder zurückgegeben wird.
        return flightR;
    }







    /* Ein FlightRealization Objekt aktualisieren.
     * @param das flightRealization Objekt, mit den aktualisierten attributen
     */
     public void update (FlightRealization flightR){

         //DB verbindung vom Connection Manager Objekt holen
        Connection con = this.manager.getConnection();

        try{

            //das departure Date Objekt aus der Flightrealization in einen sql Date umwandeln
            java.sql.Date departureDate = utilDateToSqlDate(flightR.getDateOfDeparture());

            //das arrival Date Objekt aus der Flightrealization in einen sql Date umwandeln
            java.sql.Date arrivalDate = utilDateToSqlDate(flightR.getDateOfArrival());

                //sql statement
            PreparedStatement stmt = con.prepareStatement("UPDATE flightRealization "+
                    "SET dateOfDeparture= "+"'"+departureDate+"'"+", "+
                    "dateOfArrival= "+"'"+arrivalDate+"'"+", "+
                    "flightId= "+"'"+flightR.getRelatedFlightId()+"'"+", "+
                    "craftId= "+"'"+flightR.getIdOfRelatedAircraft()+"'"+
                    " WHERE realizationId = "+"'"+flightR.getRealizationId()+"'");
            //dieser integer beinhaltet die anzahl der veränderten datensätze nach einer bestimmten UPDATE operation
            int anzahlVeraenderterDatensaetze = stmt.executeUpdate();
            }
            //falls der Zugriff auf die Klasse flightRealization scheitert
            catch(RemoteException ex){
                ex.printStackTrace();
            }

        //falls die sql abfrage fehlschlägt...
        catch (SQLException e2) {
            e2.printStackTrace();
        }

     }


     /*Eine bestimmte FlightRealization in der Datenbank löschen.
      * Die Verwaltungsklasse muss dafür sorgen, dass alle zugehörigen Buchungen gelöscht werden.
      * @param die zu löschende FlightRealization
      */
     public void delete (FlightRealization flightR){

        //DB-Verbindung vom Connection Manager holen
        Connection con = this.manager.getConnection();

        try {
            // Leeres SQL-Statement anlegen
            Statement stmt = con.createStatement();

            stmt.executeUpdate("DELETE FROM flightRealization "+
                               "WHERE realizationId = "+"'"+flightR.getRealizationId()+"'");
        }
        //falls der Zugriff auf die Klasse flightRealization fehlschlägt
        catch (RemoteException ex){
            ex.printStackTrace();
        }
        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }

     }
     
     /*Alle FlightRealizations mit der übergebenen FlightId löschen
      * @param die flightId
      */
     public void deleteAllFlightRWithAssociatedFlightId (int flightId){

        //DB-Verbindung vom Connection Manager holen
        Connection con = this.manager.getConnection();

        try {
            // Leeres SQL-Statement anlegen
            Statement stmt = con.createStatement();

            stmt.executeUpdate("DELETE FROM flightRealization "+
                               "WHERE flightId = "+"'"+flightId+"'");
        }
        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }

     }

     /*Alle FlightRealizations mit der übergebenen AircraftId löschen
      * @param die aircraftId
      */
     public void deleteAllFlightRWithAssociatedAircraftId (int craftId){

        //DB-Verbindung vom Connection Manager holen
        Connection con = this.manager.getConnection();

        try {
            // Leeres SQL-Statement anlegen
            Statement stmt = con.createStatement();

            stmt.executeUpdate("DELETE FROM flightRealization "+
                               "WHERE craftId = "+"'"+craftId+"'");
        }
        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }

     }




     /*Alle FlightRealizations, die in der Tabelle vorhanden sind werden zurückgegeben
      *
      *@return Vector mit allen FlightRealizations
      */
     public Vector<FlightRealization> findAll(){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();
         //Vector, der alle Flight Objekte festhalten wird, die in der Tabelle flight stehen
         Vector<FlightRealization> allFlightRealizations = new Vector<FlightRealization>();

         try{

             Statement stmt = con.createStatement();
             //das ergebnis der abfrage in ein ResultSet "Tabelle" abspeichern. D.h. jedes Tupel wird in eine Zeile des resultSets abgespeichert
             ResultSet allFlightRealizationQueryResult = stmt.executeQuery("SELECT realizationId, dateOfDeparture, dateOfArrival, flightId, craftId FROM flightRealization "+"ORDER BY realizationId");

             //solange die ergebnisTabelle eine nachfolgende Zeile(Datensatz) hat, wird ein neues flightRealization Objekt erstellt und zum ergebnisVector hinzugefügt.
             while(allFlightRealizationQueryResult.next()){
                 //ein neues FlightRealization Objekt anlegen, welches in den ergebnisvektor aufgenommen wird
                 FlightRealization flightR = new FlightRealizationImpl(sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfDeparture")),
                                                sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfArrival")),
                                                allFlightRealizationQueryResult.getInt("flightId"),
                                                allFlightRealizationQueryResult.getInt("craftId"));
                 flightR.setRealizationId(allFlightRealizationQueryResult.getInt("realizationId"));

                 //das gerade erstellte Objekt wird zum Ergebnisvektor hinzugefügt
                 allFlightRealizations.addElement(flightR);
             }

         }
         catch(RemoteException ex){
             ex.printStackTrace();
         }
         catch(SQLException sqlE){
             sqlE.printStackTrace();
         }
         //der vector mit allen flightRealizations aus der Tabelle wird zurückgegeben
         return allFlightRealizations;
     }


     /*Alle FlightRealizations, die in der Tabelle vorhanden sind und der  flightID übereinstimmen werden zurückgegeben
      *
      *@return Vector mit allen FlightRealizations
      */
     public Vector<FlightRealization> findAllFlightRealizationsByFlightId( int flightId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();
         //Vector, der alle Flight Objekte festhalten wird, die in der Tabelle flight stehen
         Vector<FlightRealization> allFlightRealizations = new Vector<FlightRealization>();

         try{

             Statement stmt = con.createStatement();
             //das ergebnis der abfrage in ein ResultSet "Tabelle" abspeichern. D.h. jedes Tupel wird in eine Zeile des resultSets abgespeichert
             ResultSet allFlightRealizationQueryResult = stmt.executeQuery("SELECT realizationId, dateOfDeparture, dateOfArrival, flightId, craftId FROM flightRealization "+
                                                                             "WHERE flightId = "+"'"+flightId+"'"+
                                                                             "ORDER BY realizationId");

             //solange die ergebnisTabelle eine nachfolgende Zeile(Datensatz) hat, wird ein neues flightRealization Objekt erstellt und zum ergebnisVector hinzugefügt.
             while(allFlightRealizationQueryResult.next()){
                 //ein neues FlightRealization Objekt anlegen, welches in den ergebnisvektor aufgenommen wird
                 FlightRealization flightR = new FlightRealizationImpl(sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfDeparture")),
                                                sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfArrival")),
                                                allFlightRealizationQueryResult.getInt("flightId"),
                                                allFlightRealizationQueryResult.getInt("craftId"));
                 flightR.setRealizationId(allFlightRealizationQueryResult.getInt("realizationId"));

                 //das gerade erstellte Objekt wird zum Ergebnisvektor hinzugefügt
                 allFlightRealizations.addElement(flightR);
             }

         }
         catch(RemoteException ex){
             ex.printStackTrace();
         }
         catch(SQLException sqlE){
             sqlE.printStackTrace();
         }
         //der vector mit allen flightRealizations aus der Tabelle wird zurückgegeben
         return allFlightRealizations;
     }



     /*Eine bestimmte FlightRealization abhängig von der ID finden
      *
      * @param die FlightRealization ID als integer
      * @return das gesuchte FlightRealization Objekt
      */

     public FlightRealization findById(int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         try{

             Statement stmt = con.createStatement();

             ResultSet desiredFlightrealization = stmt.executeQuery("SELECT realizationId, dateOfDeparture, dateOfArrival, flightId, craftId FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

             //es gibt nur eine FlightRealization mit gleicher ID. Es wird zunächst geschaut ob, ein FlightRealization in der ResultSet "Tabelle" ist
             if(desiredFlightrealization.next()){
                 //den ergebnisDatensatz in ein Objekt umwandeln
                 FlightRealization flightR = new FlightRealizationImpl(sqlDateToUtilDate(desiredFlightrealization.getDate("dateOfDeparture")),
                                                sqlDateToUtilDate(desiredFlightrealization.getDate("dateOfArrival")),
                                                desiredFlightrealization.getInt("flightId"),
                                                desiredFlightrealization.getInt("craftId"));
                 flightR.setRealizationId(desiredFlightrealization.getInt("realizationId"));
                 //das gefundene flightRealization Objekt zurückgeben
                 return flightR;
             }

         }
         //falls der Zugriff auf die Klasse flightRealization fehlschlägt
        catch (RemoteException ex){
            ex.printStackTrace();
            return null;
        }
        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
            return null;
        }
        //wenn keine FlightRealization gefunden wurde und keine Fehlermeldung ausgegeben wurde, gibt die Methode null zurück.
         return null;
     }

     /*Eine bestimmte FlightID abhängig von der Realization ID finden
      *
      * @param die realizationId als integer
      * @return das gesuchte Flight Objekt
      */

     public int findFlightIdByRealizationId (int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         try{

             Statement stmt = con.createStatement();

             ResultSet desiredFlightrealization = stmt.executeQuery("SELECT flightId FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

             //es gibt nur ein Flight mit gleicher ID. Es wird zunächst geschaut ob, ein Flight in der ResultSet "Tabelle" ist
             if(desiredFlightrealization.next()){
                 //den ergebnisDatensatz in ein Objekt umwandeln
                 int flightId = desiredFlightrealization.getInt("flightId");

                 return flightId;
             }

             }


        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
            return 0;
        }
        //wenn kein Flight gefunden wurde und keine Fehlermeldung ausgegeben wurde, gibt die Methode die zahl 0 zurück.
         return 0;
     }

     /*Eine bestimmte AircraftID abhängig von der Realization ID finden
      *
      * @param die realizationId als integer
      * @return die gesuchte aircraftId
      */

     public int findAircraftIdByRealizationId (int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         try{

             Statement stmt = con.createStatement();

             ResultSet desiredAircraft = stmt.executeQuery("SELECT craftId FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

                 //es gibt nur ein Flight mit gleicher ID. Es wird zunächst geschaut ob, ein Flight in der ResultSet "Tabelle" ist
                 if(desiredAircraft.next()){
                     //den ergebnisDatensatz in ein Objekt umwandeln
                     int craftId = desiredAircraft.getInt("craftId");

                     return craftId;
                 }

             }


        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
            return 0;
        }
        //wenn kein Aircraft gefunden wurde und keine Fehlermeldung ausgegeben wurde, gibt die Methode die zahl 0 zurück.
         return 0;
     }


     /*Alle FlightRealizations, die den übergebenen Flug assoziiert haben
      *
      *@return Vector mit allen FlightRealizations
      */
     public Vector<FlightRealization> findAllFlightRAssociatedWithFlightId(int flightId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();
         //Vector, der alle Flight Objekte festhalten wird, die in der Tabelle flight stehen
         Vector<FlightRealization> allFlightRealizations = new Vector<FlightRealization>();

         try{

             Statement stmt = con.createStatement();
             //das ergebnis der abfrage in ein ResultSet "Tabelle" abspeichern. D.h. jedes Tupel wird in eine Zeile des resultSets abgespeichert
             ResultSet allFlightRealizationQueryResult = stmt.executeQuery("SELECT realizationId, dateOfDeparture, dateOfArrival, flightId, craftId FROM flightRealization "+
                                                                            "WHERE flightId = "+"'"+flightId+"'"+"ORDER BY realizationId");

             //solange die ergebnisTabelle eine nachfolgende Zeile(Datensatz) hat, wird ein neues flightRealization Objekt erstellt und zum ergebnisVector hinzugefügt.
             while(allFlightRealizationQueryResult.next()){
                 //ein neues FlightRealization Objekt anlegen, welches in den ergebnisvektor aufgenommen wird
                 FlightRealization flightR = new FlightRealizationImpl(sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfDeparture")),
                                                sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfArrival")),
                                                allFlightRealizationQueryResult.getInt("flightId"),
                                                allFlightRealizationQueryResult.getInt("craftId"));
                 flightR.setRealizationId(allFlightRealizationQueryResult.getInt("realizationId"));

                 //das gerade erstellte Objekt wird zum Ergebnisvektor hinzugefügt
                 allFlightRealizations.addElement(flightR);
             }

         }
         catch(RemoteException ex){
             ex.printStackTrace();
         }
         catch(SQLException sqlE){
             sqlE.printStackTrace();
         }
         //der vector mit allen flightRealizations aus der Tabelle wird zurückgegeben
         return allFlightRealizations;
     }


     /*Alle FlightRealizations, die das übergebene Flugzeug assoziiert haben
      *
      *@return Vector mit allen FlightRealizations
      */
     public Vector<FlightRealization> findAllFlightRAssociatedWithAircraftId(int craftId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();
         //Vector, der alle Flight Objekte festhalten wird, die in der Tabelle flight stehen
         Vector<FlightRealization> allFlightRealizations = new Vector<FlightRealization>();

         try{

             Statement stmt = con.createStatement();
             //das ergebnis der abfrage in ein ResultSet "Tabelle" abspeichern. D.h. jedes Tupel wird in eine Zeile des resultSets abgespeichert
             ResultSet allFlightRealizationQueryResult = stmt.executeQuery("SELECT realizationId, dateOfDeparture, dateOfArrival, flightId, craftId FROM flightRealization "+
                                                                            "WHERE craftId = "+"'"+craftId+"'"+"ORDER BY realizationId");

             //solange die ergebnisTabelle eine nachfolgende Zeile(Datensatz) hat, wird ein neues flightRealization Objekt erstellt und zum ergebnisVector hinzugefügt.
             while(allFlightRealizationQueryResult.next()){
                 //ein neues FlightRealization Objekt anlegen, welches in den ergebnisvektor aufgenommen wird
                 FlightRealization flightR = new FlightRealizationImpl(sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfDeparture")),
                                                sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfArrival")),
                                                allFlightRealizationQueryResult.getInt("flightId"),
                                                allFlightRealizationQueryResult.getInt("craftId"));
                 flightR.setRealizationId(allFlightRealizationQueryResult.getInt("realizationId"));

                 //das gerade erstellte Objekt wird zum Ergebnisvektor hinzugefügt
                 allFlightRealizations.addElement(flightR);
             }

         }
         catch(RemoteException ex){
             ex.printStackTrace();
         }
         catch(SQLException sqlE){
             sqlE.printStackTrace();
         }
         //der vector mit allen flightRealizations aus der Tabelle wird zurückgegeben
         return allFlightRealizations;
     }


     /*Alle FlightRealizations, die in dem vorgegebenen Zeitraum stattfinden
      *@param das Start- und Enddatum des Zeitraums in Form eines java.util.date objektes
      *@return Vector mit allen FlightRealizations
      */
     public Vector<FlightRealization> findAllFlightRealizationsByTimeframe(Date startDate, Date endDate){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();
         //Vector, der alle Flight Objekte festhalten wird, die in der Tabelle flight stehen
         Vector<FlightRealization> allFlightRealizations = new Vector<FlightRealization>();

         try{

             //die zwei daten werte von java.util.date in java.sql.date umgewandelt
             java.sql.Date startDateSql = utilDateToSqlDate(startDate);
             java.sql.Date endDateSql = utilDateToSqlDate(endDate);

             Statement stmt = con.createStatement();
             //das ergebnis der abfrage in ein ResultSet "Tabelle" abspeichern. D.h. jedes Tupel wird in eine Zeile des resultSets abgespeichert
             ResultSet allFlightRealizationQueryResult = stmt.executeQuery("SELECT realizationId, dateOfDeparture, dateOfArrival, flightId, craftId FROM flightRealization "+
                                                                            "WHERE dateOfDeparture >= "+"'"+startDateSql+"'"+
                                                                            "AND dateOfArrival <= "+"'"+endDateSql+"'"+"ORDER BY realizationId");

             //solange die ergebnisTabelle eine nachfolgende Zeile(Datensatz) hat, wird ein neues flightRealization Objekt erstellt und zum ergebnisVector hinzugefügt.
             while(allFlightRealizationQueryResult.next()){
                 //ein neues FlightRealization Objekt anlegen, welches in den ergebnisvektor aufgenommen wird
                 FlightRealization flightR = new FlightRealizationImpl(sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfDeparture")),
                                                sqlDateToUtilDate(allFlightRealizationQueryResult.getDate("dateOfArrival")),
                                                allFlightRealizationQueryResult.getInt("flightId"),
                                                allFlightRealizationQueryResult.getInt("craftId"));
                 flightR.setRealizationId(allFlightRealizationQueryResult.getInt("realizationId"));

                 //das gerade erstellte Objekt wird zum Ergebnisvektor hinzugefügt
                 allFlightRealizations.addElement(flightR);
             }

         }
         catch(RemoteException ex){
             ex.printStackTrace();
         }
         catch(SQLException sqlE){
             sqlE.printStackTrace();
         }
         //der vector mit allen flightRealizations aus der Tabelle wird zurückgegeben
         return allFlightRealizations;
     }






     /*Die Gesamtanzahl von Sitzplätzen für eine bestimmte FlightRealization ermitteln
      *
      * @param die realizationId, die der FlightRealization zugeordnet ist als integer
      * @return Gesamtsitzeanzahl als integer. Sollte die Methode die zahl null zurückgeben, ist die Methode fehlgeschlagen
      */

     public int getNumberOfAllSeats(int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         //integer, der die gesamtsitzeanzahl festhält
         int numberOfAllSeats = 0;

         try{

             Statement stmt0 = con.createStatement();

             ResultSet desiredCraftId = stmt0.executeQuery("SELECT craftId FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredCraftId.next();
                 //die abgefragte craftTypeId abspeichern
                 int craftId = desiredCraftId.getInt("craftId");


             Statement stmt = con.createStatement();

             ResultSet desiredCraftTypeId = stmt.executeQuery("SELECT craftTypeId FROM aircraft "+
                                                           "WHERE craftId = "+"'"+craftId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredCraftTypeId.next();
                 //die abgefragte craftTypeId abspeichern
                 int craftTypeId = desiredCraftTypeId.getInt("craftTypeId");



                        Statement stmt2 = con.createStatement();

                        ResultSet desiredSeatId = stmt2.executeQuery("SELECT seatId FROM typeOfAircraft "+
                                                                   "WHERE craftTypeId = "+"'"+craftTypeId+"'");

                        //es muss überprüft werden, ob die abfrage ein resultat hat.
                        desiredSeatId.next();
                        //die zurückgegebene seatId abspeichern
                        int seatId = desiredSeatId.getInt("seatId");

                                //jetzt erst erfolgt die abfrage für die gesamtanzahl von sitzen für die ermittelte sitzplatzstruktur

                                Statement stmt3 = con.createStatement();

                                ResultSet desiredNumberOfAllSeats = stmt3.executeQuery("SELECT numberOfAllSeats FROM seat "+
                                                                           "WHERE seatId = "+"'"+seatId+"'");

                                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                                 desiredNumberOfAllSeats.next();
                                 //das ergebnis wird jetzt in die rückgabe variable geschrieben
                                 numberOfAllSeats = desiredNumberOfAllSeats.getInt("numberOfAllSeats");

                //die gefundene gesamtsitzeanzahl zurückgeben.
                return numberOfAllSeats;


         }

        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }

         return numberOfAllSeats;
     }



     /*Die Gesamtanzahl von Sitzplätzen Pro Reihe für eine bestimmte FlightRealization (bzw. dessen Flugzeugs) ermitteln
      *
      * @param die realizationId, die der FlightRealization zugeordnet ist als integer
      * @return Gesamtsitzeanzahl der Sitze pro Reihe als integer. Sollte die Methode die zahl null zurückgeben, ist die Methode fehlgeschlagen
      */

     public int getNumberOfSeatsPerRow(int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         //integer, der die gesamtsitzeanzahl festhält
         int numberOfSeatsPerRow = 0;

         try{

             Statement stmt0 = con.createStatement();

             ResultSet desiredCraftId = stmt0.executeQuery("SELECT craftId FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredCraftId.next();
                 //die abgefragte craftTypeId abspeichern
                 int craftId = desiredCraftId.getInt("craftId");


             Statement stmt = con.createStatement();

             ResultSet desiredCraftTypeId = stmt.executeQuery("SELECT craftTypeId FROM aircraft "+
                                                           "WHERE craftId = "+"'"+craftId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredCraftTypeId.next();
                 //die abgefragte craftTypeId abspeichern
                 int craftTypeId = desiredCraftTypeId.getInt("craftTypeId");



                        Statement stmt2 = con.createStatement();

                        ResultSet desiredSeatId = stmt2.executeQuery("SELECT seatId FROM typeOfAircraft "+
                                                                   "WHERE craftTypeId = "+"'"+craftTypeId+"'");

                        //es muss überprüft werden, ob die abfrage ein resultat hat.
                        desiredSeatId.next();
                        //die zurückgegebene seatId abspeichern
                        int seatId = desiredSeatId.getInt("seatId");

                                //jetzt erst erfolgt die abfrage für die gesamtanzahl von sitzen pro Reihe für die ermittelte sitzplatzstruktur

                                Statement stmt3 = con.createStatement();

                                ResultSet desiredSeatsPerRow = stmt3.executeQuery("SELECT seatsPerRow FROM seat "+
                                                                           "WHERE seatId = "+"'"+seatId+"'");

                                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                                 desiredSeatsPerRow.next();
                                 //das ergebnis wird jetzt in die rückgabe variable geschrieben
                                 numberOfSeatsPerRow = desiredSeatsPerRow.getInt("seatsPerRow");

                //die gefundene gesamtsitzeanzahl zurückgeben.
                return numberOfSeatsPerRow;


         }

        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }

         return numberOfSeatsPerRow;
     }



     /*Die Gesamtanzahl von Sitzreihen für eine bestimmte FlightRealization (bzw. dessen Flugzeugs) ermitteln
      *
      * @param die realizationId, die der FlightRealization zugeordnet ist als integer
      * @return Gesamtanzahl von Reihen als integer. Sollte die Methode die zahl null zurückgeben, ist die Methode fehlgeschlagen
      */

     public int getNumberOfRows(int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         //integer, der die gesamtsitzeanzahl festhält
         int numberOfRows = 0;

         try{

             Statement stmt0 = con.createStatement();

             ResultSet desiredCraftId = stmt0.executeQuery("SELECT craftId FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredCraftId.next();
                 //die abgefragte craftTypeId abspeichern
                 int craftId = desiredCraftId.getInt("craftId");


             Statement stmt = con.createStatement();

             ResultSet desiredCraftTypeId = stmt.executeQuery("SELECT craftTypeId FROM aircraft "+
                                                           "WHERE craftId = "+"'"+craftId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredCraftTypeId.next();
                 //die abgefragte craftTypeId abspeichern
                 int craftTypeId = desiredCraftTypeId.getInt("craftTypeId");



                        Statement stmt2 = con.createStatement();

                        ResultSet desiredSeatId = stmt2.executeQuery("SELECT seatId FROM typeOfAircraft "+
                                                                   "WHERE craftTypeId = "+"'"+craftTypeId+"'");

                        //es muss überprüft werden, ob die abfrage ein resultat hat.
                        desiredSeatId.next();
                        //die zurückgegebene seatId abspeichern
                        int seatId = desiredSeatId.getInt("seatId");

                                //jetzt erst erfolgt die abfrage für die gesamtanzahl von sitzen pro Reihe für die ermittelte sitzplatzstruktur

                                Statement stmt3 = con.createStatement();

                                ResultSet desiredNumberOfRows = stmt3.executeQuery("SELECT numberOfRows FROM seat "+
                                                                           "WHERE seatId = "+"'"+seatId+"'");

                                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                                 desiredNumberOfRows.next();
                                 //das ergebnis wird jetzt in die rückgabe variable geschrieben
                                 numberOfRows = desiredNumberOfRows.getInt("numberOfRows");

                //die gefundene gesamtsitzeanzahl zurückgeben.
                return numberOfRows;


         }

        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }

         return numberOfRows;
     }

     /*Diese Methode gibt die momentane Position des Pointers für Seats per Row für eine spezielle FlightRealization aus.
      *
      * @param die realizationId, die der FlightRealization zugeordnet ist als integer
      * @return Die Position des Pointers als integer
      */

     public int getPointerSpR(int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         //integer, der die pointer position festhält
         int positionPointerSpR = 0;

         try{

             Statement stmt = con.createStatement();

             ResultSet desiredPointerPosition = stmt.executeQuery("SELECT pointerSpR FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredPointerPosition.next();
                 //die abgefragte pointerPosition abspeichern
                 positionPointerSpR = desiredPointerPosition.getInt("pointerSpR");

                 return positionPointerSpR;

         }

        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }
        //dieses return gibt den standard wert 0 zurück.
         return positionPointerSpR;
     }


     /*Diese Methode gibt die momentane Position des Pointers für die aktuelle Reihe für eine spezielle FlightRealization aus.
      *
      * @param die realizationId, die der FlightRealization zugeordnet ist als integer
      * @return Die Position des Pointers als integer
      */

     public int getPointerR(int realizationId){

         //DB-Verbindung vom Connection Manager holen
         Connection con = this.manager.getConnection();

         //integer, der die pointer position festhält
         int positionPointerR = 0;

         try{

             Statement stmt = con.createStatement();

             ResultSet desiredPointerPosition = stmt.executeQuery("SELECT pointerR FROM flightRealization "+
                                                           "WHERE realizationId = "+"'"+realizationId+"'");

                 //es muss überprüft werden, ob die abfrage ein resultat hat.
                 desiredPointerPosition.next();
                 //die abgefragte pointerPosition abspeichern
                 positionPointerR = desiredPointerPosition.getInt("pointerR");

                 return positionPointerR;

         }

        //falls der sql Befehl fehlschlägt
        catch (SQLException e2) {
            e2.printStackTrace();
        }
        //dieses return gibt den standard wert 0 zurück.
         return positionPointerR;
     }


     /* Das Attribut pointerSpR in der Tabelle flightRealization aktualisieren. Diese Aktualisierung findet statt, wenn eine neue Buchung für diese flightRealization vollzogen wurde..
     * @param die id der betroffenen flightRealization und den aktuellen wert des pointers.
     */
     public void setPointerSpR (int realizationId, int updatedValueOfPointerSpR){

         //DB verbindung vom Connection Manager Objekt holen
        Connection con = this.manager.getConnection();

        try{
                //sql statement
            PreparedStatement stmt = con.prepareStatement("UPDATE flightRealization "+
                    "SET pointerSpR= "+"'"+updatedValueOfPointerSpR+"'"+
                    " WHERE realizationId = "+"'"+realizationId+"'");
            //dieser integer beinhaltet die anzahl der veränderten datensätze nach einer bestimmten UPDATE operation. In diesem Fall immer 1, da nur eine Realization mit derselben ID existiert.
            int anzahlVeraenderterDatensaetze = stmt.executeUpdate();
            
            }

        //falls die sql abfrage fehlschlägt...
        catch (SQLException e2) {
            e2.printStackTrace();
        }

     }


     /* Das Attribut pointerR in der Tabelle flightRealization aktualisieren. Diese Aktualisierung findet statt, wenn eine neue Buchung für diese flightRealization vollzogen wurde..
     * @param die id der betroffenen flightRealization und den aktuellen wert des pointers.
     */
     public void setPointerR (int realizationId, int updatedValueOfPointerR){

         //DB verbindung vom Connection Manager Objekt holen
        Connection con = this.manager.getConnection();

        try{
                //sql statement
            PreparedStatement stmt = con.prepareStatement("UPDATE flightRealization "+
                    "SET pointerR= "+"'"+updatedValueOfPointerR+"'"+
                    " WHERE realizationId = "+"'"+realizationId+"'");
            //dieser integer beinhaltet die anzahl der veränderten datensätze nach einer bestimmten UPDATE operation. In diesem Fall immer 1, da nur eine Realization mit derselben ID existiert.
            int anzahlVeraenderterDatensaetze = stmt.executeUpdate();

            }

        //falls die sql abfrage fehlschlägt...
        catch (SQLException e2) {
            e2.printStackTrace();
        }

     }




     //helfer Methode für die Umwandlung von Sql Date in java.util.Date
    //Quelle: http://blog.mynotiz.de/programmieren/mysql-timestamp-in-java-date-umwandeln-und-umgekehrt-285/
    public Date sqlDateToUtilDate(java.sql.Date sqlDate){
        
         if(sqlDate == null){
             java.sql.Date nullWerte = new java.sql.Date(0);
             Date dateNullWerte = new Date(nullWerte.getTime());
             return dateNullWerte;
         }
        else{
            Date date = new Date(sqlDate.getTime());
            return date;
         }
  }


    //helfer Methode für die Umwandlung von java.util.Date in sql.Date
    //Quelle: http://blog.mynotiz.de/programmieren/mysql-timestamp-in-java-date-umwandeln-und-umgekehrt-285/
    public java.sql.Date utilDateToSqlDate(Date date){

        java.sql.Date sqlDate = new java.sql.Date(date.getTime());
        return sqlDate;
  }



}



